﻿
using System.Globalization;
using XYS.Core.Util;

namespace XYS.Service.Core.Util.Helper
{
    /// <summary>
    /// 字符串 抱住类
    /// </summary>
    public static class StringHelper
    {
        /// <summary>
        /// 判断字符串 是否是数字开头
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDigitStart(string input) => !string.IsNullOrEmpty(input) && char.IsDigit(input[0]);

        /// <summary>
        /// 是否为有效的18位身份证号
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsValidIdCard(string input)
        {
            string id = input.ToUpper();
            // 基本长度检查
            if (id.IsNullOrWhiteSpace() || id.Length != 18)
                return false;

            // 前17位必须为数字，最后一位可以是数字或X/x
            for (int i = 0; i < 17; i++) if (!char.IsDigit(id[i])) return false;

            char lastChar = id[17];
            if (!(char.IsDigit(lastChar) || lastChar == 'X'))
                return false;

            // 验证地区码（前两位）
            if (!int.TryParse(id.Substring(0, 2), out int regionCode) || regionCode < 11 || regionCode > 91)
                return false;

            // 验证出生日期
            if (!DateTime.TryParseExact(id.Substring(6, 8), "yyyyMMdd", CultureInfo.InvariantCulture,
                DateTimeStyles.None, out DateTime birthDate))
                return false;

            // 出生日期合理性检查
            if (birthDate.Year < 1900 || birthDate > DateTime.Today)
                return false;

            // 计算校验码
            int[] weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            char[] checkCodes = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };

            int sum = 0;
            for (int i = 0; i < 17; i++)
                sum += (id[i] - '0') * weights[i];

            int remainder = sum % 11;
            char expectedCheckCode = checkCodes[remainder];

            // 验证校验码
            return char.ToUpperInvariant(lastChar) == expectedCheckCode;
        }

    }
}
